import { Row, Col, Steps, Button, Space } from "antd";
import { StepProps } from ".";
import FormRender, { useForm, Error as FormRenderError } from "form-render";
import { useCallback, useEffect, useState } from "react";
import ContentSkeleton from "src/components/contentSkeleton";
import { useRuntimeManifest } from "../../api";

function extractProperty(propertyDescriptor: any, defaultValue: any) {
  const { displayName: title, description, required } = propertyDescriptor;
  const enumValues = [];
  const enumNames = [];
  if (propertyDescriptor.allowableValues) {
    for (const allowableValue of propertyDescriptor.allowableValues) {
      const { value, displayName } = allowableValue;
      enumValues.push(value);
      enumNames.push(displayName);
    }
    return {
      title,
      description,
      type: "string",
      required,
      enum: enumValues,
      enumNames,
      widget: 'select',
      default: defaultValue,
    }
  }
  return {
    title,
    description,
    type: "string",
    required,
    default: defaultValue,
  }
}

function extractSchema(item: any, bundles: any) {
  const { type, properties } = item;
  for (const bundle of bundles) {
    const { componentManifest: { controllerServices, processors } } = bundle;
    for (const cs of [...controllerServices, ...processors]) {
      if (cs.type === type) {
        const { propertyDescriptors } = cs;
        return {
          type: 'object',
          properties: Object.fromEntries(
            Object.keys(propertyDescriptors).map(
              (key: string) => [key, extractProperty(propertyDescriptors[key], properties[key])]
            ))
        }
      }
    }
  }
}

const result: any[] = [];
const Content: React.FC<StepProps> = ({ data, onStepDataUpdated }) => {
  const [schemaObjectList, setSchemaObjectList] = useState<any[]>([]);
  const [currentStep, setCurrentStep] = useState(0);

  const { runtimeManifest: { bundles } } = useRuntimeManifest();

  useEffect(() => {
    onStepDataUpdated(null);

    // 解析数据，生成 components
    const { flowContents: { controllerServices, processors } } = JSON.parse(data[0]);
    setSchemaObjectList([...controllerServices, ...processors].map((item: any) => {
      const { name: title, comments: description } = item;
      return { title, description, schema: extractSchema(item, bundles) };
    }));
  }, [data, bundles, onStepDataUpdated]);

  const form = useForm();
  const onFinish = useCallback((formData: any, errors: FormRenderError[]) => {
    console.error('formData:', formData, 'errors', errors);
    if (errors && errors.length) {
      return;
    }
    result[currentStep] = formData;
    if (currentStep === schemaObjectList.length - 1) {
      onStepDataUpdated(result);
    }
    setCurrentStep(currentStep + 1);
  },[currentStep, onStepDataUpdated, schemaObjectList]);

  return schemaObjectList.length ?
    <Row gutter={24}>
      <Col push={1} span={8}>
        <Steps current={currentStep} direction="vertical">
          {schemaObjectList.map(obj => <Steps.Step title={obj.title} description={obj.description} />)}
          <Steps.Step title="参数设置完成" description="完成任务参数设置" />
        </Steps>
      </Col>
      <Col span={15}>
        {currentStep < schemaObjectList.length ? <>
          <p>
            <h1>{schemaObjectList[currentStep].title}</h1>
            <span>{schemaObjectList[currentStep].description}</span>
          </p>
          <FormRender form={form} schema={schemaObjectList[currentStep].schema} onFinish={onFinish} />
        </> : <>
          <p>
            <h1>参数设置完成</h1>
            <span>您已完成参数设置。请单击下一步设置任务调度。</span>
          </p>
        </>}
        <Space>
          <Button type="default" onClick={() => setCurrentStep(currentStep - 1)} disabled={!currentStep}>上一步</Button>
          <Button type="primary" onClick={() => form.submit()} disabled={currentStep === schemaObjectList.length}>下一步</Button>
        </Space>
      </Col>
    </Row>
    : <ContentSkeleton />;
};

export default Content;